package model

import (
	"database/sql"
	"fmt"
	"github.com/jmoiron/sqlx"
	"github.com/pkg/errors"
	"strconv"
	"zimuzu_cvn_web_api/config"
	. "zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
	"zimuzu_cvn_web_api/service/rrapi"
)

var EtherscanUrl = "https://eth.btc.com/txinfo/"

type UidList struct {
	Uid int64 `db:"uid,omitempty" form:"uid" json:"uid"`
}

type User struct {
	Uid             int64          `db:"uid" json:"uid"`
	Sex             int            `db:"sex" json:"sex"`
	PhoneArea       int            `db:"phone_area" json:"phone_area"`
	GroupId         int            `db:"group_id" json:"group_id"`
	MainGroupId     int            `db:"main_group_id" json:"main_group_id"`
	KuoZhanGroupDay int            `db:"kuozhan_group_day" json:"kuozhan_group_day"`
	CommonGroupId   int            `db:"common_group_id" json:"common_group_id"`
	Level           int            `db:"level" json:"level"`
	Threads         int            `db:"threads" json:"threads"`
	Point           int            `db:"point" json:"point"`
	LastLoginTime   int            `db:"last_login_time" json:"last_login_time"`
	LoginCount      int            `db:"login_count" json:"login_count"`
	TypeId          int            `db:"type_id" json:"type_id"`
	UpdateTime      int            `db:"update_time" json:"update_time"`
	CreateUid       int            `db:"create_uid" json:"create_uid"`
	CreateTime      int            `db:"create_time" json:"create_time"`
	CreateIp        int            `db:"create_ip" json:"create_ip"`
	Status          int            `db:"status" json:"status"`
	AdminStatus     int            `db:"admin_status" json:"admin_status"`
	Source          int            `db:"source" json:"source"`
	ChangePwd       int            `db:"change_pwd" json:"change_pwd"`
	Password        string         `db:"password" json:"password"`
	Email           string         `db:"email,omitempty" json:"email"`
	Salt            string         `db:"salt" json:"salt"`
	Nickname        string         `db:"nickname,omitempty" json:"nickname"`
	PhoneNumber     string         `db:"phone_number" json:"phone_number"`
	Signature       string         `db:"signature,omitempty" json:"signature"`
	Pinyin          string         `db:"pinyin" json:"pinyin"`
	UserPic         string         `db:"userpic" json:"userpic"`
	LastLoginIp     string         `db:"last_login_ip" json:"last_login_ip"`
	ActiveCode      sql.NullString `db:"activecode,omitempty" json:"activecode"`
	Did             string         `db:"did,omitempty" json:"did"`
	RegistrationId  string         `db:"registration_id,omitempty" json:"registration_id"`
	AndriodDid      string         `db:"andriod_did,omitempty" json:"andriod_did"`
}

//注册的字段
type RegisterUser struct {
	Uid         int64  `db:"uid,omitempty" json:"uid"`
	Salt        string `db:"salt,omitempty" json:"salt"`
	Nickname    string `db:"nickname,omitempty" json:"nickname"`
	PinYin      string `db:"pinyin,omitempty" json:"pinyin"`
	Password    string `db:"password,omitempty" json:"password"`
	PhoneArea   int    `db:"phone_area,omitempty" json:"phone_area"`
	CreateIp    int64  `db:"create_ip,omitempty" json:"create_ip"`
	Source      int    `db:"source,omitempty" json:"source"`
	UserPic     string `db:"userpic,omitempty" json:"userpic"`
	PhoneNumber string `db:"phone_number,omitempty" json:"phone_number"`
}

//用户路由器挖矿上传统计信息
type RouterUploadInfo struct {
	TotalSize    sql.NullInt64 `db:"total_size,omitempty" json:"total_size"`
	ExchangeSize sql.NullInt64 `db:"exchange_size,omitempty" json:"exchange_size"`
	UpdateTime   sql.NullInt64 `db:"update_time,omitempty" json:"update_time"`
}

type UserNode struct {
	Normal int `json:"normal"`
	Miner  int `json:"miner"`
	Belief int `json:"belief"`
}

// 使用设置model
type UsageMode struct {
	Language int `form:"language" json:"language"`
	Currency int `form:"currency" json:"currency"`
}

// 校验
type UniqueKey struct {
	U string `form:"u" json:"u"`
}

type PasswordModel struct {
	Password string `form:"password" json:"password"`
}

type MiningInfoResponse struct {
	LastCvn       float64 `json:"lastCvn"`       //昨日收益
	TotalCvn      float64 `json:"totalCvn"`      //累计收益
	LastFlow      string  `json:"lastFlow"`      //昨日贡献量
	UserTotalFlow string  `json:"userTotalFlow"` //累计贡献量
	TotalFlow     string  `json:"totalFlow"`     //昨日全网贡献量
	LastAllCvn    float64 `json:"lastAllCvn"`    //昨日全网CDN收入
	Rate          string  `json:"rate"`          //用户占全网比例
	UserWithCvn   float64 `json:"userWithCvn"`   //用户可用余额
	UserUnWithCvn float64 `json:"UserUnWithCvn"` //用户不可用余额
	PledgeNums    int     `json:"pledgeNums"`    //质押节点数
	UnPledgeNums  int     `json:"unPledgeNums"`  //非质押节点数
}

type UserMobile struct {
	Area   int    `db:"phone_area" json:"area"`
	Mobile string `db:"phone_number" json:"mobile"`
}

type UidTokenParams struct {
	Uid   int64  `form:"uid" json:"uid" binding:"required"`
	Token string `form:"token" json:"token" binding:"required"`
}

//通过手机号查询账号信息
//Auth: Xu
func GetUserByMobile(db sqlx.Queryer, mobile string, area int) (User, error) {
	var user User
	err := sqlx.Get(db, &user, `select uid,salt,password,phone_area,phone_number,email,nickname,userpic,point from user where phone_number = ? and phone_area = ? limit 1`, mobile, area)
	if err == sql.ErrNoRows {
		return user, errors.New("账号信息不存在")
	}
	if err != nil {
		Log("err", mobile, ":获取账号信息失败")
		return user, err
	}

	return user, nil
}

//根据用户名查询账户信息
func GetUserByName(db sqlx.Queryer, name string) (User, error) {
	var qi User
	err := sqlx.Get(db, &qi, `select uid,salt,password,phone_area,phone_number,email,nickname,userpic,point from user where nickname = ? limit 1`, name)
	if err != nil {
		return qi, err
	}

	return qi, nil
}

//通过uid查询账号信息
//Auth: Xu
func GetUserByUid(db sqlx.Queryer, uid int64) (User, error) {
	var user User
	err := sqlx.Get(db, &user, `select uid,salt,password,phone_area,phone_number,email,nickname,userpic,point from user where uid = ? limit 1`, uid)
	if err == sql.ErrNoRows {
		return user, errors.New("账号信息不存在")
	}
	if err != nil {
		Log("err", uid, ":获取账号信息失败")
		return user, err
	}

	return user, nil
}

func RegisterInitCount(db sqlx.Execer, uid int64) (int, error) {
	re := sqlx.MustExec(db, `INSERT INTO user_count (uid) VALUES (?)`, uid)
	reply, err := re.LastInsertId()
	if err != nil {
		return 0, err
	}
	return int(reply), nil
}

func RegisterInitUserExtend(db sqlx.Execer, uid int64) (int, error) {
	re := sqlx.MustExec(db, `INSERT INTO user_extend (uid) VALUES (?)`, uid)
	reply, err := re.LastInsertId()
	if err != nil {
		return 0, err
	}
	return int(reply), nil
}

func RegisterInitUserStatus(db sqlx.Execer, uid, ip int64) (int, error) {
	re := sqlx.MustExec(db, `INSERT INTO user_status (uid,lastvisit,lastactivity,create_time,regip,lastip,create_ip,lastpost,lastreadfav,lastsendmsg,lastreadsysmessage,invisible,status)
VALUES (?,UNIX_TIMESTAMP(NOW()),UNIX_TIMESTAMP(NOW()),UNIX_TIMESTAMP(NOW()),?,?,?,0,0,0,0,0,0)`, uid, ip, ip, ip)
	reply, err := re.LastInsertId()
	if err != nil {
		return 0, err
	}
	return int(reply), nil
}

func RegisterCreateUser(db sqlx.Execer, qi *RegisterUser) (int64, error) {
	var re sql.Result
	re = sqlx.MustExec(db, `INSERT INTO user (salt, nickname, password, phone_area, phone_number, pinyin, point, userpic, type_id, create_ip, status, common_group_id) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 52)`,
		qi.Salt, qi.Nickname, qi.Password, qi.PhoneArea, qi.PhoneNumber, qi.PinYin, 0, qi.UserPic, 0, qi.CreateIp)
	uid, err := re.LastInsertId()
	if err != nil {
		return 0, err
	}

	return uid, nil
}

//更新用户全部信息
//Auth:Xu
func ReplaceUser(db sqlx.Execer, info rrapi.RRUserInfo) (err error) {
	_, err = db.Exec(`REPLACE  INTO user (uid, salt, nickname, password, phone_area, phone_number, pinyin, point, userpic, type_id, create_ip, status, common_group_id) 
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 52)`,
		info.Uid, info.Salt, info.Nickname, info.Password, info.PhoneArea, info.PhoneNumber, "", 0, info.UserPic, 0, 0)
	if err != nil {
		Log("err", "ReplaceUser"+err.Error())
	}

	return err
}

//清空用户手机号信息
//Auth:Xu
func DeleteUserMobile(db sqlx.Execer, uid int64) (err error) {
	_, err = db.Exec(`UPDATE user SET phone_number = "", phone_area = 0 WHERE uid = ?`, uid)
	if err != nil {
		Log("err", "DeleteUserMobile"+err.Error())
	}

	return err
}

/*
	source  	来源  1 路由器  2 奖励池
	uploadSize  上传流量
	cvnt   		cvnt数量
	point  		人人钻数量(source为 2时没有人人钻)
	createTime	时间
*/
type IssueRecord struct {
	Source     int     `json:"source" db:"source"`
	UploadSize string  `json:"uploadSize" db:"upload_size"`
	Cvnt       float64 `json:"cvnt" db:"cvnt"`
	Point      int     `json:"point,omitempty" db:"point"`
	CreateTime string  `json:"createTime" db:"create_time"`
	UnlockTime string  `json:"unlockTime,omitempty" db:"unlock_time,omitempty"`
}

/*
 * @ Author: hupfei
 * @ Description: 获取cvnt发放记录
 **/
func GetIssueRecordListFromDB(db sqlx.Queryer, uid int64, per, page int) (res []IssueRecord, err error) {
	start := (page - 1) * per
	err = sqlx.Select(db, &res, "SELECT * FROM "+
		"(SELECT type AS source, SUM(up) * 1024 * 1024 * 1024 AS upload_size, SUM(cvn) AS cvnt, 0 AS point, SUBSTRING(date, 6) AS create_time, \"\" AS unlock_time "+
		"FROM mg_node_payment WHERE status = 1 AND cvn > 0 AND uid = ? GROUP BY date,source "+
		"UNION ALL "+
		"SELECT 3 AS source, upload_size, cvn AS cvnt, point, FROM_UNIXTIME(create_time, '%m/%d') AS create_time, \"\" AS unlock_time "+
		"FROM cvn_user_upload_log WHERE uid = ? AND cvn > 0) "+
		"cvnt_issue_record ORDER BY create_time DESC LIMIT ?,?", uid, uid, start, per)
	if err != nil {
		Log("err", "查询cvnt发放记录失败！", err.Error())
		return nil, err
	}

	return res, nil
}

/*
 * @ Author: hupfei
 * @ Description: 官网cvn账户明细
 **/
type CVNLog struct {
	Id          int64   `json:"id" db:"id"`
	Source      int     `json:"source" db:"source"`
	Description string  `json:"description"`
	Txhash      string  `json:"txhash" db:"txhash"`
	Cvnt        float64 `json:"cvnt" db:"amount"`
	Status      int     `json:"status" db:"status"`
	WithdrawId  string  `json:"withdrawId,omitempty" db:"txhash"`
	CreateTime  string  `json:"createTime" db:"create_time"`
}

func GetCVNLogListFormDB(uid int64, per, page int) (res []CVNLog, err error) {
	start := (page - 1) * per

	sqlStr := fmt.Sprintf("SELECT id, source, amount, status, IFNULL(txhash,'') txhash, FROM_UNIXTIME(create_time, '%%Y/%%m/%%d %%H:%%i') AS create_time FROM cvn_log WHERE uid=%d AND source != %d ORDER BY id DESC LIMIT %d, %d", uid, LogSourceSystemBalancing, start, per)
	err = sqlx.Select(config.C.DB.DB, &res, sqlStr)
	if err != nil {
		Log("err", "官网cvn账户明细失败！", err.Error())
		return nil, err
	}

	return res, nil
}

/*
 * @ Author: hupfei
 * @ Description: 查询 cvnt 账户明细
   @ Params: source 0全部 1转入 2转出 3其他
 **/
func GetAccountLogListFromDB(uid int64, source, per, page int) (res []CvnLogDb, err error) {
	start := (page - 1) * per

	sqlStr := fmt.Sprintf("SELECT id, source, amount, status, create_time FROM cvn_log WHERE uid=%d AND source != %d ", uid, LogSourceSystemBalancing)
	if source == 0 {
		//全部
	} else if source == 1 {
		//转入
		sqlStr += fmt.Sprintf("AND source IN(%d, %d) ", LogSourceIn, LogSourceInnerIn)
	} else if source == 2 {
		//转出
		sqlStr += fmt.Sprintf("AND source IN(%d, %d) ", LogSourceOut, LogSourceInnerOut)
	} else if source == 3 {
		//其他
		sqlStr += fmt.Sprintf("AND source NOT IN(%d, %d, %d, %d) ", LogSourceIn, LogSourceInnerIn, LogSourceOut, LogSourceInnerOut)
	}
	sqlStr += fmt.Sprintf("ORDER BY id DESC LIMIT %d,%d", start, per)

	err = sqlx.Select(config.C.DB.DB, &res, sqlStr)
	if err != nil {
		Log("err", "查询cvnt账户明细失败！", err.Error())
		return nil, err
	}

	return res, nil
}

func GetUsdtAccountLogListFromDB(uid int64, source, per, page int) (res []UsdtLogDB, err error) {
	start := (page - 1) * per

	sqlStr := fmt.Sprintf("SELECT id, source, amount, status,  create_time FROM usdt_log WHERE uid=%d ", uid)
	if source == 0 {
		//全部
	} else if source == 1 {
		//转入
		sqlStr += fmt.Sprintf("AND source IN(%d, %d) ", LogSourceUsdtIn, LogSourceUsdtInnerIn)
	} else if source == 2 {
		//转出
		sqlStr += fmt.Sprintf("AND source IN(%d, %d) ", LogSourceUsdtOut, LogSourceUsdtInnerOut)
	} else if source == 3 {
		//其他
		sqlStr += fmt.Sprintf("AND source NOT IN(%d, %d, %d, %d) ", LogSourceUsdtIn, LogSourceUsdtInnerIn, LogSourceUsdtOut, LogSourceUsdtInnerOut)
	}
	sqlStr += fmt.Sprintf("ORDER BY id DESC LIMIT %d,%d", start, per)

	err = sqlx.Select(config.C.DB.DB, &res, sqlStr)
	if err != nil {
		Log("err", "查询usdt账户明细失败！", err.Error())
		return nil, err
	}

	return res, nil
}

//转账+充值消息
type DealMessage struct {
	Id           int64  `json:"id" db:"id"`
	Source       int    `json:"type" db:"source"`
	Cvnt         string `json:"amount" db:"amount"`
	CreateTime   string `json:"datetime" db:"create_time"`
	Currency     string `json:"currency" db:"currency"`
	Address      string `json:"address" db:"address"`
	CurrencyType int    `json:"currencyType" db:"currencyType"`
	Des          string `json:"des"`
	Status       int    `json:"-" db:"status"` //1-成功，2-失败，3-处理中
}

//获取转账+充值消息列表
//Auth: Xu
func GetDeaMessageList(uid int64, per, page int, currency string) ([]DealMessage, error) {
	res := make([]DealMessage, 0)
	start := (page - 1) * per

	err := sqlx.Select(config.C.DB.DB, &res, "SELECT id, `status`, 0 AS currencyType, source, amount, IF(source=13||source=17, `from`, `to`) AS address, "+
		"FROM_UNIXTIME(create_time, '%Y/%m/%d %H:%i') AS create_time, '"+currency+"' as currency "+
		"FROM cvn_log "+
		"WHERE uid = ? AND (source = ? or source = ? or source = ? or source = ?) ORDER BY id DESC LIMIT ?, ?",
		uid, LogSourceIn, LogSourceOut, LogSourceInnerIn, LogSourceInnerOut, start, per)
	if err != nil {
		Log("err", "查询cvnt账户明细失败！", err.Error())
		return nil, err
	}

	return res, nil
}

func GetDeaUsdtMessageList(uid int64, per, page int, currency string) ([]DealMessage, error) {
	res := make([]DealMessage, 0)
	start := (page - 1) * per

	err := sqlx.Select(config.C.DB.DB, &res, "SELECT id, `status`, 0 AS currencyType, source, amount, IF(source=101||source=102, `from`, `to`) AS address, "+
		"FROM_UNIXTIME(create_time, '%Y/%m/%d %H:%i') AS create_time, '"+currency+"' as currency "+
		"FROM usdt_log "+
		"WHERE uid = ? AND (source = ? or source = ? or source = ? or source = ?) ORDER BY id DESC LIMIT ?, ?",
		uid, LogSourceUsdtIn, LogSourceUsdtOut, LogSourceUsdtInnerIn, LogSourceUsdtInnerOut, start, per)
	if err != nil {
		Log("err", "查询usdt账户明细失败！", err.Error())
		return nil, err
	}

	return res, nil
}

//查询用户账户转账和充值记录数
//Auth: Xu
func GetAccountLogNums(db sqlx.Queryer, uid int64) (num int, err error) {
	err = sqlx.Get(db, &num, "SELECT count(*) FROM cvn_log WHERE uid= ? and (source = ? or (source = ? and status = ?) or source = ? or (source = ? and status = ?))",
		uid, LogSourceIn, LogSourceOut, DealStatusSuccess, LogSourceInnerIn, LogSourceInnerOut, DealStatusSuccess)
	if err == sql.ErrNoRows {
		err = nil
	}
	if err != nil {
		Log("err", "查询转账和充值记录数失败！", err.Error())
		return num, err
	}
	return num, nil
}

func GetUsdtLogNums(db sqlx.Queryer, uid int64) (num int, err error) {
	err = sqlx.Get(db, &num, "SELECT count(*) FROM usdt_log WHERE uid= ? and (source = ? or (source = ? and status = ?) or source = ? or (source = ? and status = ?))",
		uid, LogSourceUsdtIn, LogSourceUsdtOut, DealStatusSuccess, LogSourceUsdtInnerIn, LogSourceUsdtInnerOut, DealStatusSuccess)
	if err == sql.ErrNoRows {
		err = nil
	}
	if err != nil {
		Log("err", "查询usdt转账和充值记录数失败！", err.Error())
		return num, err
	}
	return num, nil
}

type CvnLogDetail struct {
	Id               int64   `db:"id" json:"id"`
	Uid              int64   `db:"uid" json:"uid"`
	Amount           float64 `db:"amount" json:"amount"`
	Balance          float64 `db:"balance" json:"balance"`
	RelateId         string  `db:"relate_id" json:"relate_id"`
	RelateTable      string  `db:"relate_table" json:"relate_table"`
	From             string  `db:"from" json:"from"`
	To               string  `db:"to" json:"to"`
	TxHash           string  `db:"txhash" json:"txhash"`
	Source           int     `db:"source" json:"source"`
	Status           int     `db:"status" json:"status"`
	CreateTime       string  `db:"create_time" json:"create_time"`
	UpdateTime       int64   `db:"update_time" json:"update_time"`
	Block            int64   `db:"block" json:"block"`
	BlockConfirmTime int64   `db:"block_confirm_time" json:"block_confirm_time"`
	SignString       string  `db:"sign_string" json:"sign_string"`
	SignVersion      string  `db:"sign_version" json:"sign_version"`
}

/*
 * @ Author: hupfei
 * @ Description: 查询资产详情
 **/
func GetCvnLogDetailFromDB(id int64) (info CvnLogDetail, err error) {
	err = sqlx.Get(config.C.DB.DB, &info, "SELECT source, relate_id, status, amount, block, IFNULL(`from`, '') AS `from`, IFNULL(`to`, '') AS `to`, IFNULL(txhash, '') AS txhash, "+
		"FROM_UNIXTIME(create_time, '%Y/%m/%d %H:%i') AS create_time FROM cvn_log WHERE id = ?", id)
	if err != nil {
		Log("err", "查询资产详情失败！", err.Error())
	}

	return info, err
}

type UsdtLogDetail struct {
	Id               int64   `db:"id"`
	Uid              int64   `db:"uid"`
	Amount           float64 `db:"amount"`
	Balance          float64 `db:"balance"`
	RelateId         string  `db:"relate_id"`
	RelateTable      string  `db:"relate_table"`
	From             string  `db:"from"`
	To               string  `db:"to"`
	TxHash           string  `db:"txhash"`
	Source           int     `db:"source"`
	Status           int     `db:"status"`
	CreateTime       string  `db:"create_time"`
	UpdateTime       int64   `db:"update_time"`
	Block            int64   `db:"block"`
	BlockConfirmTime int64   `db:"block_confirm_time"`
	SignString       string  `db:"sign_string"`
	SignVersion      string  `db:"sign_version"`
}

func GetUsdtLogDetailFromDB(id int64) (info UsdtLogDetail, err error) {
	err = sqlx.Get(config.C.DB.DB, &info, "SELECT source, relate_id, status, amount, block, IFNULL(`from`, '') AS `from`, IFNULL(`to`, '') AS `to`, IFNULL(txhash, '') AS txhash, "+
		"FROM_UNIXTIME(create_time, '%Y/%m/%d %H:%i') AS create_time FROM usdt_log WHERE id = ?", id)
	if err != nil {
		Log("err", "查询资产详情失败！", err.Error())
	}

	return info, err
}

//获取令牌买卖订单号和数量
func GetTokenOrderInfo(orderId int) (info TokenSaleOrder, err error) {
	err = sqlx.Get(config.C.DB.DB, &info, "SELECT order_no, deal_num FROM mg_token_sale_order WHERE id = ?", orderId)
	if err == sql.ErrNoRows {
		err = nil
	}
	if err != nil {
		Log("err", "GetTokenOrderInfo 失败！", err.Error())
		return info, err
	}

	return info, nil
}

//查询转账手续费
func GetFeeWithRelateId(relateId string, coinType int) (cvnt float64, err error) {
	sqlStr := "SELECT amount FROM "
	if coinType == 0 {
		sqlStr += "cvn_log "
	} else {
		sqlStr += "usdt_log "
	}
	sqlStr += fmt.Sprintf("WHERE id = %s", relateId)
	err = sqlx.Get(config.C.DB.DB, &cvnt, sqlStr)
	if err == sql.ErrNoRows {
		err = nil
	}
	if err != nil {
		Log("err", "查询旷工费失败！", err.Error())
	}
	return cvnt, err
}

//查询奖励池总贡献量（lx_node_flow）
func GetLinuxSizeFromDB(uid int64) (linuxSize sql.NullInt64, err error) {
	var sqlStr string
	if uid > 0 {
		sqlStr = fmt.Sprintf("SELECT sum(up) FROM mg_node_flow WHERE uid = %d and type = %d", uid, NodeTypeLinux)
	} else {
		sqlStr = "SELECT sum(up) FROM mg_node_flow where type = " + strconv.Itoa(NodeTypeLinux)
	}
	err = sqlx.Get(config.C.DB.DB, &linuxSize, sqlStr)
	if err == sql.ErrNoRows {
		err = nil
	}
	if err != nil {
		Log("err", "查询奖励池贡献量失败！", err.Error())
		return linuxSize, err
	}
	return linuxSize, nil
}

//查询路由器个人挖矿统计信息
//Auth: Xu
func GetRouterUploadInfo(db sqlx.Queryer, uid int64) (uploadInfo RouterUploadInfo, err error) {
	err = sqlx.Get(db, &uploadInfo, "SELECT total_size, exchange_size, update_time from user_upload_total where uid = ?", uid)
	if err == sql.ErrNoRows {
		err = nil
	}
	if err != nil {
		Log("info", "查询用户路由器挖矿信息失败！", err.Error())
		return
	}
	return
}

//查询用户云钱包中的cvn总数
//Auth: Xu
func GetYqbCvntCountByUid(db sqlx.Queryer, uid int64) (count sql.NullFloat64, err error) {
	err = sqlx.Get(db, &count, "SELECT sum(cvn) FROM yqb_amount where uid = ?", uid)
	if err != nil {
		Log("info", "查询用户云钱包cvnt总量失败！", err.Error())
		return count, err
	}
	return count, nil
}

//检查用户是否存在
func CheckUserExist(db sqlx.Queryer, uid int64) (bool, error) {
	var count int
	row := db.QueryRowx("SELECT count(*) FROM user WHERE uid = ?", uid)
	err := row.Scan(&count)
	if err != nil {
		return false, err
	}
	if count == 0 {
		return false, nil
	}
	return true, nil
}

type UpdaterUser struct {
	Uid        int64  `db:"uid,omitempty" json:"uid"`
	Salt       string `db:"salt,omitempty" json:"salt"`
	Nickname   string `db:"nickname,omitempty" json:"nickname"`
	PinYin     string `db:"pinyin,omitempty" json:"pinyin"`
	Password   string `db:"password,omitempty" json:"password"`
	UserPic    string `db:"userpic,omitempty" json:"userpic"`
	ChangePwd  int    `db:"change_pwd,omitempty" json:"change_pwd"`
	UpdateTime int64  `db:"update_time" json:"update_time"`
}

func UpdateUserPassword(db sqlx.Execer, qi *UpdaterUser) error {

	res, err := db.Exec("update user set password = ?, update_time = ? where uid = ?", qi.Password, qi.UpdateTime, qi.Uid)
	if err != nil {
		return err
	}
	ra, err := res.RowsAffected()
	if err != nil {
		return errors.Wrap(err, "get rows affected error")
	}
	if ra == 0 {
		return errors.New("not exist")
	}
	return nil
}

// 查询全网 CVN 总量
type TotalCvnRe struct {
	UnWithDrawnCvn       float64 `db:"unwithdrawn_cvn" form:"unwithdrawn_cvn" json:"unwithdrawn_cvn"`
	PledgingCvn          float64 `db:"pledging_cvn" form:"pledging_cvn" json:"pledging_cvn"`
	RouterPledgingCvn    float64 `db:"router_pledging_cvn" form:"router_pledging_cvn" json:"router_pledging_cvn"`
	SuperNodePledgingCvn float64 `db:"super_node_pledging_cvn" form:"super_node_pledging_cvn" json:"super_node_pledging_cvn"`
	PCPledgingCvn        float64 `db:"pc_pledging_cvn" form:"pc_pledging_cvn" json:"pc_pledging_cvn"`
}

func GetGlobalUserCvn() (totalCvnRe TotalCvnRe, err error) {
	err = sqlx.Get(config.C.DB.DB, &totalCvnRe, "SELECT SUM(`unwithdrawn_cvn`) AS unwithdrawn_cvn, SUM(`pledging_cvn`) AS pledging_cvn, SUM(`router_pledging_cvn`) AS router_pledging_cvn, SUM(`super_node_pledging_cvn`) AS super_node_pledging_cvn, SUM(`pc_pledging_cvn`) AS pc_pledging_cvn FROM user_amount WHERE 1")
	if err != nil {
		return totalCvnRe, err
	}
	return totalCvnRe, nil
}

type UnavailableInfo struct {
	Title         string `db:"title" json:"title"`
	Cvnt          string `db:"cvn" json:"cvnt"`
	Day           string `db:"day" json:"day,omitempty"`
	Type          int    `db:"type" json:"type"`
	CreateTime    string `db:"create_time" json:"createTime"`
	AvailableTime string `db:"time" json:"availableTime,omitempty"`
}

//查询router、linux质押赎回记录
func GetPledgeRedemptionList(uid int64, per, page int) (res []UnavailableInfo, err error) {
	start := (page - 1) * per
	sqlStr := fmt.Sprintf("SELECT cvn, FROM_UNIXTIME(create_time, '%%Y/%%m/%%d %%H:%%i') AS create_time, FROM_UNIXTIME(time, '%%Y/%%m/%%d %%H:%%i') AS time, time AS day, type FROM cvn_user_draw_task WHERE uid=%d AND status = 0 ORDER BY dl_id DESC LIMIT %d, %d", uid, start, per)
	err = sqlx.Select(config.C.DB.DB, &res, sqlStr)
	if err != nil {
		Log("err", "查询router、linux质押赎回记录失败！", err.Error())
		return nil, err
	}

	return res, nil
}

// 黑名单用户 user_upload_black
func GetBlackUser(Uid int64) error {
	var res int
	err := sqlx.Get(config.C.DB.DB, &res, `SELECT count(*) from user_upload_black where uid = ?`, Uid)
	if err != nil {
		res = 0
	}
	if res <= 0 {
		return errno.RecordError
	}
	return nil
}

//获取用户手机号
//Auth: TXG
func GetUserMobile(db sqlx.Queryer, uid int64) (qi UserMobile, err error) {
	err = sqlx.Get(db, &qi, `select phone_area, phone_number from user where uid = ? `, uid)
	if err != nil {
		Log("err", err)
	}
	return qi, err
}

func GetUserFromLogin(t int, Keyword string) (User UserLoginResponse, err error) {

	if t == 2 && len(Keyword) < 10 {
		t = 4
	}
	if t == 1 {
		err = sqlx.Get(config.C.DB.DB, &User, `SELECT uid, password, salt from user where nickname =?`, Keyword)
	} else if t == 2 {
		err = sqlx.Get(config.C.DB.DB, &User, `SELECT uid, password, salt from user where phone_number = ?`, Keyword)
	} else if t == 3 {
		err = sqlx.Get(config.C.DB.DB, &User, `SELECT uid, password, salt from user where email = ?`, Keyword)
	} else {
		err = sqlx.Get(config.C.DB.DB, &User, `SELECT uid, password, salt from user where uid = ?`, Keyword)
	}
	if err != nil {
		return User, err
	}
	return
}

func GetUserTokenByUidAndToken(uid int64, token string) (int, error) {
	db := config.C.DB.DB
	var count int
	err := sqlx.Get(db, &count, "select count(*) from user_token where uid = ? and token = ?", uid, token)
	if err != nil {
		return 0, err
	}
	return count, nil
}
